#include "diskMemory.h"

char* diskGetPage(int pAddress)
{
	/*char* page = malloc(pageSize*sizeof(char));
	int i;
	for (i = 0; i < pageSize; ++i)
	{
		page[i] = diskMemory[pAddress+i];
	}
	return page;*/
	return &diskMemory[pAddress*pageSize];
}

void diskSetPage(int pAddress, char* page)
{
	int i;
	for (i = pAddress; i < pageSize + pAddress; ++i)
	{
		diskMemory[i] = page[i-pAddress];
	}
}

void initDiskMemory()
{
	diskMemory = malloc(NumOfPagesInDisk*pageSize*sizeof(char));
	int i;
	for (i = 0; i < NumOfPagesInDisk*pageSize; ++i)
	{
		diskMemory[i] = 'f';
	}

	initPCB();
}

void killDiskMemory()
{
	FREE(diskMemory);
}

void initPCB()
{
	pcb = malloc(MaxNumOfProcesses*sizeof(pcbRecord));
	int i;
	for (i = 0; i < MaxNumOfProcesses; ++i)
	{
		pcb[i].pid = i;
		pcb[i].startPageIndex = NumOfProcessPages*i;
		pcb[i].isOccupied = 0;
		pcb[i].waitForPRM = malloc(sizeof(sem_t));
		pcb[i].mailbox = malloc(sizeof(blockingQueue));
		mbox_init(pcb[i].mailbox);
	}
}

//return 1 if success, 0 if no memory space
int pcbAddProcess(int processID, int startPageIndex)
{
	int i;
	int found = 0;	//var to check whether there is free space on the disk
	for (i = 0; i < MaxNumOfProcesses; ++i)
	{
		if (pcb[i].pid == -1)
		{
			pcb[i].pid = processID;
			pcb[i].startPageIndex = startPageIndex;
			pcb[i].isOccupied = 1;
			found = 1;
			break;
		}
	}
	return found;
}

void pcbRemoveProcess(int processID)
{
	int i;
	for (i = 0; i < MaxNumOfProcesses; ++i)
	{
		if (pcb[i].pid == processID)
		{
			pcb[i].isOccupied = 0;
			break;
		}
	}
}

//Returns the process page start index
int pcbGetProcessPageStartIndex(int processID)
{
	int i;
	for (i = 0; i < MaxNumOfProcesses; ++i)
	{
		if (pcb[i].pid == processID)
			return pcb[i].startPageIndex;
	}
	return -1;
}

void killPCB()
{
	int i;
	for (i = 0; i < MaxNumOfProcesses; ++i)
	{
		FREE(pcb[i].waitForPRM);
		mbox_kill(pcb[i].mailbox);
	}
	free(pcb);
}

void printDisk(){
	int i, j;
	for (i = 0; i < NumOfPagesInDisk; i++){
		for (j = 0; j < pageSize; j++){
			printf("%c ",diskMemory[pageSize*i+j]);
		}
		printf("\n");
	}
}
